using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;


namespace FoundationLib.Ifc.Domain 
{
	/// <summary>
	/// Provides an interface for a message bus
	/// </summary>
	public interface IMessageBus : IDisposable 
	{
		/// <summary>
		/// Registers the given action as a message handler
		/// </summary>
		/// <param name="handler">The action delegate serving as a message handler</param>
		void Subscribe<T>(Action<T> handler) where T : IMessage;

		/// <summary>
		/// Registers the given message handler
		/// </summary>
		/// <param name="handler">The message handler</param>
		void Subscribe<T>(IHandles<T> handler) where T : IMessage;

		/// <summary>
		/// Sends a message to the bus
		/// </summary>
		/// <param name="command">The command to send to the bus</param>
		void Send<T>(T command) where T : ICommand;

		/// <summary>
		/// Removes all subscriptions made explicitly with this bus
		/// </summary>
		void ClearSubscriptions();

		/// <summary>
		/// Publishes the given event to the bus
		/// </summary>
		/// <param name="domainEvent">The domain event published to the bus</param>
		void Publish<T>(T domainEvent) where T : IEvent;
	}

}